﻿
Public Class distributingTM
    Inherits threadModel

    Private tp As threadpool = Nothing

    Public Property threadCount() As Int64
        Get
            Return tp.threadCount()
        End Get
        Set(ByVal value As Int64)
            tp.threadCount() = value
        End Set
    End Property

    Public Sub New()
        MyBase.new()
        tp = New threadpool(AddressOf work)
    End Sub

    Public Overrides Sub [stop]()
        tp.stop()
        MyBase.[stop]()
    End Sub

    Private Class info
        Public rst As ternary = Nothing
        Public finish As Boolean = False
        Public d As _do(Of ternary) = Nothing
    End Class

    Private Sub work(ByVal i As info)
        assert(Not i Is Nothing)
        assert(Not i.d Is Nothing)
        assert(Not i.finish)
        i.rst = i.d()
        i.finish = True
    End Sub

    Private Sub work(ByVal obj As Object)
        work(convertor.cast(Of info)(obj))
    End Sub

    Protected Overrides Function operImpl(ByVal d As _do(Of ternary), ByVal operationCount As Int64) As ternary
        assert(Not d Is Nothing)
        assert(operationCount > 0)
        Dim startticks As Int64 = 0
        startticks = Now.Ticks()
        Dim infos(operationCount - 1) As info
        Dim i As Int64 = 0
        For i = 0 To operationCount - 1
            infos(i) = New info()
            infos(i).d = d
            tp.insertJob(infos(i))
        Next

        Dim rtn As ternary = ternary.unknown
        i = 0
        While i < operationCount AndAlso Not overtimelimit(startticks)
            While Not infos(i).finish AndAlso Not overtimelimit(startticks)
                sleep(1)
            End While
            If Not infos(i).finish Then
                Return ternary.false
            End If
            rtn = returnValue(infos(i).rst, rtn)
            i += 1
        End While

        If i = operationCount Then
            Return rtn
        Else
            Return ternary.false
        End If
    End Function

    Public Shared Sub register(ByVal resolver As resolver)
        resolver.register(Of threadModel)(Function() As threadModel
                                              Return New distributingTM()
                                          End Function)
    End Sub

    Public Shared Sub register()
        register(resolver.global)
    End Sub
End Class
